package com.zzl.mine.pojo.page;

import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

/**
 * @description 页面请求参数封装Map
 * @author rambo
 * @date 2018年7月9日 上午10:41:31
 */
@SuppressWarnings("rawtypes")
public class PageData extends HashMap implements Map {

	private static final long serialVersionUID = 1L;

	Map map = null;
	HttpServletRequest request;

	/**
	 * @description 自定义带参构造函数，封装页面请求的入参
	 * @param request HttpServletRequest
	 */
	@SuppressWarnings("unchecked")
	public PageData(HttpServletRequest request) {
		this.request = request;
		Map properties = request.getParameterMap();
		Map returnMap = new HashMap();//Map实例化具体类型我们使用HashMap
		Iterator entries = properties.entrySet().iterator();
		Map.Entry entry;
		String name = "";
		String value = "";
		while (entries.hasNext()) {
			entry = (Map.Entry) entries.next();
			name = (String) entry.getKey();
			Object valueObj = entry.getValue();
			if (null == valueObj) {
				value = "";
			} else if (valueObj instanceof String[]) {
				String[] values = (String[]) valueObj;
				for (int i = 0; i < values.length; i++) {
					value = values[i] + ",";
				}
				value = value.substring(0, value.length() - 1);
			} else {
				value = valueObj.toString();
			}
			returnMap.put(name, value);
		}
		map = returnMap;
	}

	/**
	 * @description 无参构造函数，如果使用这个构造函数实例化本类对象，需要先使用put方法才能get到数据
	 */
	public PageData() {
		map = new HashMap();
	}

	/**
	 * 说明：如果页面请求参数name相同的有多个，那么我们只取第一个，也就是说为了保证请求的可靠性，我们要保证name唯一，即使不唯一也要做到name对应的value相同
	 * @description 根据键key获取值value
	 * @param key 键key
	 * @return 返回值value
	 */
	@Override
	public Object get(Object key) {
		Object obj = null;
		if (map.get(key) instanceof Object[]) {
			Object[] arr = (Object[]) map.get(key);
			obj = request == null ? arr : (request.getParameter((String) key) == null ? arr : arr[0]);
		} else {
			obj = map.get(key);
		}
		return obj;
	}

	/**
	 * @description 根据键key获取值value，我们在已知值value是字符串类型的情况下使用该方法比较方便
	 * @param key 键key
	 * @return 返回值value
	 */
	public String getString(Object key) {
		return (String) get(key);
	}

	/**
	 * @description 往Map中添加键值对
	 * @param key 键
	 * @param value 值
	 * @return 如果已经存在一个相同的key， 则返回的是前一个key对应的value，同时该key的新value覆盖旧value；如果是新的一个key，则返回的是null
	 */
	@SuppressWarnings("unchecked")
	@Override
	public Object put(Object key, Object value) {
		return map.put(key, value);
	}

	/**
	 * @description 根据指定的键删除Map中的键值对
	 * @param key 键
	 * @return 返回值为key对应的value
	 */
	@Override
	public Object remove(Object key) {
		return map.remove(key);
	}

	/**
	 * @description 清除Map集合里面所有的键值对，但是map对象不置空，如果想置空对象释放内存空间使用=null
	 */
	public void clear() {
		map.clear();
	}

	/**
	 * @description 判断Map集合是否包含键等于key的键值对
	 * @param key 键
	 * @return 如果Map集合包含键等于key的键值对那么就返回true，否则返回false
	 */
	public boolean containsKey(Object key) {
		return map.containsKey(key);
	}

	/**
	 * @description 判断Map集合是否包含值等于value的键值对
	 * @param value 值
	 * @return 如果Map集合包含值等于value的键值对那么就返回true，否则返回false
	 */
	public boolean containsValue(Object value) {
		return map.containsValue(value);
	}

	/**
	 * @description 获取所有的键值对以Set集合存储的形式，Set泛型对象其实就是封装了键值对的Map.Entry对象
	 * @return 返回Map.Entry的Set集合
	 */
	public Set entrySet() {
		return map.entrySet();
	}

	/**
	 * @description 判断map是否包含键值对
	 * @return 如果包含至少一个键值对那么就返回false，否则返回true
	 */
	public boolean isEmpty() {
		return map.isEmpty();
	}

	/**
	 * @description 获取Map中所有的key，以Set集合存储的形式
	 * @return 返回所有的key以Set集合存储的形式
	 */
	public Set keySet() {
		return map.keySet();
	}

	/**
	 * @description 往Map中添加map，需要指出的是添加的是map中的key/value，而不是value为map
	 * @param t 待添加的map
	 */
	@SuppressWarnings("unchecked")
	public void putAll(Map t) {
		map.putAll(t);
	}

	/**
	 * @description 获取Map中键值对的个数
	 * @return 返回Map中键值对的个数
	 */
	public int size() {
		return map.size();
	}

	/**
	 * @description 获取Map中的所有的value封装成的集合
	 * @return 返回所有value组成的集合
	 */
	public Collection values() {
		return map.values();
	}

}
